// This file is part of the RECODER library and protected by the LGPL.

package recodercs.csharp.expression.operator;

import recodercs.csharp.*;
import recodercs.csharp.expression.*;
import recodercs.csharp.reference.*;
import recodercs.list.*;

import java.io.*;

/**
 Type cast.
 @author <TT>AutoDoc</TT>
 */

public class TypeCast extends TypeOperator {

    /**
     Type cast.
     */

    public TypeCast() {}

    /**
     Note: The ordering of the arguments does not match the syntactical
     appearance of a Java type case, but the order in the superclass
     TypeOperator. However, getASTChildren yields them in the right
     order.
     */

    public TypeCast(Expression child, TypeReference typeref) {
        super(child, typeref);
        makeParentRoleValid();
    }

    /**
     Type cast.
     @param proto a type cast.
     */

    protected TypeCast(TypeCast proto) {
        super(proto);
        makeParentRoleValid();
    }

    /**
     Deep clone.
     @return the object.
     */

    public Object deepClone() {
        return new TypeCast(this);
    }

    /**
     Returns the number of children of this node.
     @return an int giving the number of children of this node
    */

    public int getChildCount() {
        int result = 0;
        if (typeReference != null) result++;
        if (children      != null) result += children.size();
        return result;
    }

    /**
     Returns the child at the specified index in this node's "virtual"
     child array
     @param index an index into this node's "virtual" child array
     @return the program element at the given position
     @exception ArrayIndexOutOfBoundsException if <tt>index</tt> is out
                of bounds
    */

    public ProgramElement getChildAt(int index) {
        int len;
        if (typeReference != null) {
            if (index == 0) return typeReference;
            index--;
        }
        if (children != null) {
            len = children.size();
            if (len > index) {
                return children.getProgramElement(index);
            }
            index -= len;
        }
        throw new ArrayIndexOutOfBoundsException();
    }

    /**
     Get arity.
     @return the int value.
     */

    public int getArity() {
        return 1;
    }

    /**
     Get precedence.
     @return the int value.
     */

    public int getPrecedence() {
        return 1;
    }

    /**
     Get notation.
     @return the int value.
     */

    public int getNotation() {
        return PREFIX;
    }

    /**
       Checks if this operator is left or right associative. Type casts
       are right associative.
       @return <CODE>true</CODE>, if the operator is left associative,
       <CODE>false</CODE> otherwise.
     */

    public boolean isLeftAssociative() {
        return false;
    }

    public void accept(SourceVisitor v) {
        v.visitTypeCast(this);
    }
}
